package com.zhongwang.mms.module.buy.controller;

import com.alibaba.excel.EasyExcel;
import com.zhongwang.mms.base.BaseController;
import com.zhongwang.mms.common.JsonResult;
import com.zhongwang.mms.gen.entity.User;
import com.zhongwang.mms.module.basic.dao.DictCommonDao;
import com.zhongwang.mms.module.basic.model.DictCommon;
import com.zhongwang.mms.module.buy.dao.BPreOrderPlanDao;
import com.zhongwang.mms.module.buy.model.*;
import com.zhongwang.mms.module.buy.service.BuyProcurementPlanService;
import com.zhongwang.mms.module.system.log.LogService;
import com.zhongwang.mms.util.FileUtils;
import com.zhongwang.mms.util.ShiroUtils;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("/buy/preOrderDetails")
public class BuyPreOrderDetailsController extends BaseController {
    @Autowired
    private BPreOrderPlanDao bPreOrderPlanDao;
    @Autowired
    private BuyProcurementPlanService buyProcurementPlanService;
    @Autowired
    private LogService logService;
    @Autowired
    private DictCommonDao dictCommonDao;
    /**
     * 上传文件路径
     */
    @Value("${user.upload.path}")
    private String uploadPath;



    /**
     * 跳转到预购明细列表
     * @param model
     * @return
     */
    @GetMapping("/page")
    public String page(Model model) {
        List<DictCommon> dictCommonList = dictCommonDao.findDictByGroupName("票据类型");
        model.addAttribute("dictCommonList", dictCommonList);
        return "/buy/preOrderPlan/preOrderDetails/page";
    }

    /**
     * 查询采购计划列表 -- 明细模式 - 普通搜索
     *
     * @param where 搜索条件
     * @return 采购计划列表
     */
    @ResponseBody
    @RequestMapping("/list")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    public JsonResult list(BPreOrderPlan where) {
        startPage();
        List<BPreOrderPlan> list = buyProcurementPlanService.findDetailsProcurementPlanByQuery(where);
        return jsonResult(list);
    }
    /**
     * 查询预购明细列表 -- 明细模式 - 高级搜索
     *
     * @param where 搜索条件
     * @return 采购计划列表
     */
    @ResponseBody
    @RequestMapping("/advanceList")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    public JsonResult advanceList(BPreOrderPlan where) {
        startPage();
        List<BPreOrderPlan> list = buyProcurementPlanService.findDetailsProcurementPlanByQueryForAdvanceList(where);
        return jsonResult(list);
    }

    /**
     * 查询采购计划列表 -- 汇总模式
     * @param where 搜索条件
     * @return 采购计划列表
     */
    @ResponseBody
    @RequestMapping("/summaryList")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    public JsonResult summaryList(BPreOrderPlan where) {
        startPage();
        List<BPreOrderPlan> list = buyProcurementPlanService.findDetailsProcurementSummaryListPlanByQuery(where);
        return jsonResult(list);
    }



    /**
     * 导出 Excel
     * @param where 搜索条件
     * @param response 下载使用
     * @return 下载文件流
     */
    @PostMapping("/exportExcel")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    @ResponseBody
    public ResponseEntity<byte[]> exportExcel(BPreOrderPlan where, HttpServletResponse response) throws IOException {
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        logService.saveLog("采购计划编辑——导出", "执行导出操作，开始导出数据！");
        //获取当前登录用户
        User user = ShiroUtils.getUser();
        //获取当前登录用户可以导出的Excel的列表数据
        List<BPreOrderPlan> list = bPreOrderPlanDao.selectProcurementPlanByWhere(where);
        //拼装成导出Excel所需要的列表
        List<ProcurementPlanDetailsExportImportModel> exportModels = new ArrayList<>();
        for (BPreOrderPlan preOrderPlan : list) {
            ProcurementPlanDetailsExportImportModel ProcurementPlanDetailsExportImportModel = new ProcurementPlanDetailsExportImportModel();
            ProcurementPlanDetailsExportImportModel.setTrackNumber(preOrderPlan.getTrackNumber());
            ProcurementPlanDetailsExportImportModel.setMaterialDesc(preOrderPlan.getMaterialDesc());
            ProcurementPlanDetailsExportImportModel.setProCode(preOrderPlan.getProCode());
            ProcurementPlanDetailsExportImportModel.setProName(preOrderPlan.getProName());
            ProcurementPlanDetailsExportImportModel.setNum(preOrderPlan.getNum());
            ProcurementPlanDetailsExportImportModel.setUnit(preOrderPlan.getUnit());
            ProcurementPlanDetailsExportImportModel.setPcNo(preOrderPlan.getPcNo());
            ProcurementPlanDetailsExportImportModel.setPurchNum(preOrderPlan.getPurchNum());
            ProcurementPlanDetailsExportImportModel.setReceivedNum(preOrderPlan.getReceivedNum());
            ProcurementPlanDetailsExportImportModel.setPurchUnit(preOrderPlan.getPurchUnit());
            ProcurementPlanDetailsExportImportModel.setTaxRate(preOrderPlan.getTaxRate());
            ProcurementPlanDetailsExportImportModel.setBillType(preOrderPlan.getBillType());
            ProcurementPlanDetailsExportImportModel.setUnitPrice(preOrderPlan.getUnitPrice());
            ProcurementPlanDetailsExportImportModel.setTotalPrice(preOrderPlan.getTotalPrice());
            ProcurementPlanDetailsExportImportModel.setSupplier(preOrderPlan.getSupplier());
            ProcurementPlanDetailsExportImportModel.setPurchCreate(preOrderPlan.getPurchCreate());
            ProcurementPlanDetailsExportImportModel.setExportRecord(preOrderPlan.getExportRecord());
            ProcurementPlanDetailsExportImportModel.setApplicant(preOrderPlan.getApplicant().replace("<br>"," "));
            ProcurementPlanDetailsExportImportModel.setPurchaser(preOrderPlan.getPurchaser());
            ProcurementPlanDetailsExportImportModel.setPreOrderRemark(preOrderPlan.getPreOrderRemark());
            ProcurementPlanDetailsExportImportModel.setPurchRemark(preOrderPlan.getPurchRemark());
            ProcurementPlanDetailsExportImportModel.setCreateTime(preOrderPlan.getCreateTime());
            ProcurementPlanDetailsExportImportModel.setName(preOrderPlan.getName());
            ProcurementPlanDetailsExportImportModel.setCode(preOrderPlan.getCode());
            if (preOrderPlan.getPcNo() == null || "".equals(preOrderPlan.getPcNo())) {
                ProcurementPlanDetailsExportImportModel.setPurchStatus("未采购");
            }else{
                ProcurementPlanDetailsExportImportModel.setPurchStatus("已采购");
            }
            if (preOrderPlan.getReceiptStatus() == 1){
                ProcurementPlanDetailsExportImportModel.setReceiptStatus("未收货");
            }else  if (preOrderPlan.getReceiptStatus() == 2){
                ProcurementPlanDetailsExportImportModel.setReceiptStatus("已收货");
            }else  if (preOrderPlan.getReceiptStatus() == 3){
                ProcurementPlanDetailsExportImportModel.setReceiptStatus("无需收货");
            }else if (preOrderPlan.getReceiptStatus() == 4){
                ProcurementPlanDetailsExportImportModel.setReceiptStatus("部分收货");
            }
            try{
                ProcurementPlanDetailsExportImportModel.setReceivedProcess((ProcurementPlanDetailsExportImportModel.getReceivedNum().divide(ProcurementPlanDetailsExportImportModel.getPurchNum(), 4, RoundingMode.HALF_UP).doubleValue()*100d)+"%");
            }catch (Exception e){
                ProcurementPlanDetailsExportImportModel.setReceivedProcess("0.0%");
            }
            exportModels.add(ProcurementPlanDetailsExportImportModel);
        }
        //获取票据类型列表
        List<DictCommon> dictCommonList = dictCommonDao.findDictByGroupName("票据类型");
        //导出Excel所需的String类型列表
        List<String> billTypeList = new ArrayList<>();
        //拼装导出Excel所需的String类型列表
        for (DictCommon dc : dictCommonList) {
            billTypeList.add(dc.getName());
        }
        //创建内存
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //采用EasyExcel将数据写入到内存中
        EasyExcel.write(bos, ProcurementPlanDetailsExportImportModel.class)
                .registerWriteHandler(new RedHeadStyleHandler(ProcurementPlanDetailsExportImportModel.class))         // 9 列红色背景 处理器
                .registerWriteHandler(new InvoiceTypeDropdownHandler(billTypeList, 5000)) // 下拉框 处理器
                .sheet("sheet1")//sheet名字
                .doWrite(exportModels);//开始写入
        String fileName =  URLEncoder.encode("采购计划编辑", "UTF-8").replace("+", "%20");
        // 记录结束时间（纳秒）
        long endTime = System.nanoTime();
        // 计算耗时（秒）
        double elapsedSeconds = (endTime - startTime) / 1_000_000_000.0;
        //记录操作日志
        logService.saveLog("采购计划编辑——导出", "执行导出操作，导出"+exportModels.size()+"行数据,耗时"+elapsedSeconds+"秒！");
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + fileName + ".xlsx")
                .body(bos.toByteArray());
    }
    /**
     * 导出 Excel - 高级搜索
     * @param where 搜索条件
     * @param response 下载使用
     * @return 下载文件流
     */
    @PostMapping("/exportExcelForAdvanced")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    @ResponseBody
    public ResponseEntity<byte[]> exportExcelForAdvanced(BPreOrderPlan where,HttpServletResponse response) throws IOException {
        //获取当前登录用户
        User user = ShiroUtils.getUser();
        //获取当前登录用户可以导出的Excel的列表数据
        List<BPreOrderPlan> list = bPreOrderPlanDao.findProcurementPlanByQueryForAdvanceList(where);
        //拼装成导出Excel所需要的列表
        List<ProcurementPlanDetailsExportImportModel> exportModels = new ArrayList<>();
        for (BPreOrderPlan preOrderPlan : list) {
            ProcurementPlanDetailsExportImportModel ProcurementPlanDetailsExportImportModel = new ProcurementPlanDetailsExportImportModel();
            ProcurementPlanDetailsExportImportModel.setTrackNumber(preOrderPlan.getTrackNumber());
            ProcurementPlanDetailsExportImportModel.setMaterialDesc(preOrderPlan.getMaterialDesc());
            ProcurementPlanDetailsExportImportModel.setProCode(preOrderPlan.getProCode());
            ProcurementPlanDetailsExportImportModel.setProName(preOrderPlan.getProName());
            ProcurementPlanDetailsExportImportModel.setNum(preOrderPlan.getNum());
            ProcurementPlanDetailsExportImportModel.setUnit(preOrderPlan.getUnit());
            ProcurementPlanDetailsExportImportModel.setPcNo(preOrderPlan.getPcNo());
            ProcurementPlanDetailsExportImportModel.setPurchNum(preOrderPlan.getPurchNum());
            ProcurementPlanDetailsExportImportModel.setPurchUnit(preOrderPlan.getPurchUnit());
            ProcurementPlanDetailsExportImportModel.setTaxRate(preOrderPlan.getTaxRate());
            ProcurementPlanDetailsExportImportModel.setBillType(preOrderPlan.getBillType());
            ProcurementPlanDetailsExportImportModel.setUnitPrice(preOrderPlan.getUnitPrice());
            ProcurementPlanDetailsExportImportModel.setTotalPrice(preOrderPlan.getTotalPrice());
            ProcurementPlanDetailsExportImportModel.setSupplier(preOrderPlan.getSupplier());
            ProcurementPlanDetailsExportImportModel.setPurchCreate(preOrderPlan.getPurchCreate());
            ProcurementPlanDetailsExportImportModel.setExportRecord(preOrderPlan.getExportRecord());
            ProcurementPlanDetailsExportImportModel.setApplicant(preOrderPlan.getApplicant().replace("<br>"," "));
            ProcurementPlanDetailsExportImportModel.setPurchaser(preOrderPlan.getPurchaser());
            ProcurementPlanDetailsExportImportModel.setPreOrderRemark(preOrderPlan.getPreOrderRemark());
            ProcurementPlanDetailsExportImportModel.setPurchRemark(preOrderPlan.getPurchRemark());
            ProcurementPlanDetailsExportImportModel.setCreateTime(preOrderPlan.getCreateTime());
            ProcurementPlanDetailsExportImportModel.setName(preOrderPlan.getName());
            ProcurementPlanDetailsExportImportModel.setCode(preOrderPlan.getCode());
            if (preOrderPlan.getPcNo() == null || "".equals(preOrderPlan.getPcNo())) {
                ProcurementPlanDetailsExportImportModel.setPurchStatus("未采购");
            }else{
                ProcurementPlanDetailsExportImportModel.setPurchStatus("已采购");
            }
            if (preOrderPlan.getReceiptStatus() == 1){
                ProcurementPlanDetailsExportImportModel.setReceiptStatus("未收货");
            }else if (preOrderPlan.getReceiptStatus() == 2){
                ProcurementPlanDetailsExportImportModel.setReceiptStatus("已收货");
            }else if (preOrderPlan.getReceiptStatus() == 3){
                ProcurementPlanDetailsExportImportModel.setReceiptStatus("无需收货");
            }else if (preOrderPlan.getReceiptStatus() == 4){
                ProcurementPlanDetailsExportImportModel.setReceiptStatus("部分收货");
            }
            exportModels.add(ProcurementPlanDetailsExportImportModel);

        }
        //获取票据类型列表
        List<DictCommon> dictCommonList = dictCommonDao.findDictByGroupName("票据类型");
        //导出Excel所需的String类型列表
        List<String> billTypeList = new ArrayList<>();
        //拼装导出Excel所需的String类型列表
        for (DictCommon dc : dictCommonList) {
            billTypeList.add(dc.getName());
        }
        //创建内存
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //采用EasyExcel将数据写入到内存中
        EasyExcel.write(bos, ProcurementPlanDetailsExportImportModel.class)
                .registerWriteHandler(new RedHeadStyleHandler(ProcurementPlanDetailsExportImportModel.class)) // 下拉框 处理器
                .registerWriteHandler(new InvoiceTypeDropdownHandler(billTypeList, 5000)) // 下拉框 处理器
                .sheet("sheet1")//sheet名字
                .doWrite(exportModels);//开始写入
        String fileName =  URLEncoder.encode("采购计划编辑", "UTF-8").replace("+", "%20");
        //记录操作日志
        logService.saveLog("采购计划编辑——导出", "执行导出操作，导出"+exportModels.size()+"行数据！");
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + fileName + ".xlsx")
                .body(bos.toByteArray());
    }
    /**
     * 根据预购编号code查询预购计划列表
     * @param code 预购编号
     * @return 预购计划列表
     */
    @ResponseBody
    @PostMapping("/getProOrderPlanListByCode")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    public JsonResult getProOrderPlanListByCode(String code) {
        List<BPreOrderPlan> list = buyProcurementPlanService.findBPreOrderPlanByCode(code);
        return success().setData(list);
    }

    /**
     * 根据预购计划ID判断附件文件是否存在
     * @param id
     * @return
     */
    @ResponseBody
    @PostMapping("/getAttachmentIsExist")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    public JsonResult getAttachmentIsExist(Integer id) {
        BPreOrderPlan preOrderPlan = buyProcurementPlanService.getBPreOrderPlanByPrimaryKey(id);
        String attachmentUrl = preOrderPlan.getAttachment();
        String msg = "有文件";
        if(attachmentUrl == null || attachmentUrl.equals("")){
            msg = "没有文件";
        }else{
            attachmentUrl = attachmentUrl.replace("/files/", "/");
            String localPath = uploadPath + attachmentUrl.substring(attachmentUrl.indexOf("/"));
            if(new File(localPath).exists()) {
                return success(msg);
            }
        }
        return error(msg);
    }

    /**
     * 根据预购计划ID下载附件
     * @param id 预购计划ID
     */
    @GetMapping("/downloadAttachment/{id}")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    public ResponseEntity<Resource> downloadAttachment(@PathVariable("id") Integer id,
                                                       HttpServletResponse httpServletResponse,
                                                       HttpServletRequest request) throws MalformedURLException {
        BPreOrderPlan preOrderPlan = buyProcurementPlanService.getBPreOrderPlanByPrimaryKey(id);
        String attachmentUrl = preOrderPlan.getAttachment();
        attachmentUrl = attachmentUrl.replace("/files/", "/");
        String localPath = uploadPath + attachmentUrl.substring(attachmentUrl.indexOf("/"));
        Path realPath = Paths.get(localPath); // 真实文件
        Resource resource = new UrlResource(realPath.toUri());
        if (!resource.exists()) {
            return ResponseEntity.notFound().build();
        }else{
            // 根据浏览器类型决定编码方式
            String agent = request.getHeader("User-Agent");
            String disposition = "attachment; filename*=UTF-8''" + UriUtils.encode(preOrderPlan.getAttachmentName(), StandardCharsets.UTF_8);
            logService.saveLog("采购管理-采购计划编辑", "下载预购主题为：" + preOrderPlan.getName() + "，预购编码为：" + preOrderPlan.getCode() + ",物料跟踪码为：" + preOrderPlan.getTrackNumber() + ",物料描述为：" + preOrderPlan.getMaterialDesc() + "的名称为：" + preOrderPlan.getAttachmentName() + "的附件（附件大小：" + FileUtils.formatFileSize(realPath.toFile().length()) + "）！");
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .header(HttpHeaders.CONTENT_DISPOSITION, disposition)
                    .body(resource);
        }
    }



    /**
     * 获取票据类型列表
     * @return
     */
    @ResponseBody
    @PostMapping("/getBillTypeList")
    @RequiresPermissions(value = {"buy:preorderdetails:view"}, logical = Logical.OR)
    public JsonResult getBillTypeList() {
        Integer res = 0;
        //获取票据类型列表
        List<DictCommon> dictCommonList = dictCommonDao.findDictByGroupName("票据类型");
        res = dictCommonList.size();
        if (res > 0) {
            return success().setData(dictCommonList);
        }
        return error("操作失败！");
    }
}
